﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Net.Http;

namespace XUtility
{

    #region  String 类型 扩展方法

    public static class StringEx
    {
        #region 返回 Int32 类型
        /// <summary>
        /// 返回 Int32 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <returns>Int32 类型</returns>
        public static Int32 ToInt32(this String s)
        {
            return s.ToInt32(0);
        }
        /// <summary>
        /// 返回 Int32 类型
        /// <para>字符是Double类型的处理，四舍五入</para>
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="v">默认值</param>
        /// <returns>Int32 类型</returns>
        public static Int32 ToInt32(this String s, Int32 v)
        {
            Int32 result = 0;
            if (s.HasValue())
            {
                #region 字符是Double类型的处理，四舍五入
                Int32 temp = 0;
                Int32 index = s.IndexOf('.');
                if (index > -1)
                {
                    temp = Int32.Parse(s.Substring(index + 1, 1)) > 4 ? 1 : 0;
                    s = s.Substring(0, index);
                }
                #endregion

                if (!Int32.TryParse(s, out result))
                {
                    result = v;
                }
                result += temp;
            }

            return result;
        }
        #endregion

        #region 返回 Double 类型
        /// <summary>
        /// 返回 Double 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <returns>Double 类型</returns>
        public static Double ToDouble(this String s)
        {
            return s.ToDouble(0D);
        }
        /// <summary>
        /// 返回 Double 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="v">默认值</param>
        /// <returns>Double 类型</returns>
        public static Double ToDouble(this String s, Double v)
        {
            Double result;
            if (!Double.TryParse(s, out result))
            {
                result = v;
            }

            return result;
        }
        #endregion

        #region 返回 Decimal 类型
        /// <summary>
        /// 返回 Decimal 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <returns>Decimal 类型</returns>
        public static Decimal ToDecimal(this String s)
        {
            return s.ToDecimal(0M);
        }
        /// <summary>
        /// 返回 Decimal 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="scale">小数位数</param>
        /// <returns>Decimal 类型</returns>
        public static Decimal ToDecimal(this String s, Int32 scale)
        {
            return s.ToDecimal(0M, scale);
        }
        /// <summary>
        /// 返回 Decimal 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="v">默认值</param>
        /// <returns>Decimal 类型</returns>
        public static Decimal ToDecimal(this String s, Decimal v)
        {
            return s.ToDecimal(v, -1);
        }
        /// <summary>
        /// 返回 Decimal 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="v">默认值</param>
        /// <param name="scale">小数位数</param>
        /// <returns>Decimal 类型</returns>
        public static Decimal ToDecimal(this String s, Decimal v, Int32 scale)
        {
            Decimal result;
            if (!Decimal.TryParse(s, out result))
            {
                result = v;
            }
            if (scale > 0)
            {
                result = Math.Round(result, scale);
            }
            return result;
        }
        #endregion

        #region 返回 Boolean 类型
        /// <summary>
        /// 返回 Boolean 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <returns>Boolean 类型</returns>
        public static Boolean ToBoolean(this String s)
        {
            return s.ToBoolean(false);
        }
        /// <summary>
        /// 返回 Boolean 类型
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="v">默认值</param>
        /// <returns>Boolean 类型</returns>
        public static Boolean ToBoolean(this String s, Boolean v)
        {
            Boolean result;
            if ("1".Equals(s) || "true".Equals(s, StringComparison.OrdinalIgnoreCase))
            {
                result = true;
            }
            else if ("0".Equals(s) || "false".Equals(s, StringComparison.OrdinalIgnoreCase) || String.IsNullOrWhiteSpace(s))
            {
                result = false;
            }
            else
            {
                if (!Boolean.TryParse(s, out result))
                {
                    result = v;
                }
            }

            return result;
        }
        #endregion

        #region 返回bytes[]类型
        /// <summary>
        /// 返回bytes[]类型
        /// </summary>
        /// <param name="s">原字符串</param>
        /// <returns></returns>
        public static byte[] ToBytes(this String s)
        {
            return System.Text.Encoding.Default.GetBytes(s);
        } 
        #endregion

        #region 返回 DateTime 类型
        /// <summary>
        /// 转为日期
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <param name="v">可空默认值,如果转换失败，同时v是空值，则返回日期最小值</param>
        /// <returns>DateTime 类型</returns>
        public static DateTime ToDateTime(this String s, DateTime? v = null)
        {
            var dt = DateTime.MinValue;
            if (DateTime.TryParse(s, out dt))
            {
                return dt;
            }

            if (v == null)
            {
                return dt;
            }
            else
            {


                return v.Value;
            }

        }

        /// <summary>
        /// 转为Unix日期
        /// </summary>
        /// <param name="timeStamp">输入字符串</param>
        /// <param name="v">可空默认值,如果转换失败，同时v是空值，则返回日期最小值</param>
        /// <returns>DateTime 类型</returns>
        public static DateTime ToUnixDateTime(this String timeStamp, DateTime? v = null)
        {
            var dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            var lTime = 0l;
            if (timeStamp.Length == 13)
            {
                lTime = long.Parse(timeStamp + "0000");
            }
            else
            {
                lTime = long.Parse(timeStamp + "0000000");
            }
            var toNow = new TimeSpan(lTime);
            var dtResult = dtStart.Add(toNow);
            return dtResult;
        }
        #endregion

        /// <summary>
        /// 返回Enum类型
        /// </summary>
        /// <param name="str">输入对象值</param>
        /// <returns>Enum类型</returns>
        public static TEnum ToEnum<TEnum>(this String str) where TEnum : struct
        {
            TEnum t = default(TEnum);

            if (!typeof(TEnum).IsEnum)
                throw new ArgumentException("T must be an enumerated type");
            if (String.IsNullOrEmpty(str))
                throw new ArgumentException("T must be not Null Or Empty");

            Enum.TryParse(str, out t);

            return t;
        }


        /// <summary>
        /// 返回base64编码后的字符串
        /// </summary>
        /// <param name="s">原字符串</param>
        /// <returns></returns>
        public static String ToBase64(this String s)
        {
            return Convert.ToBase64String(s.ToBytes());
        }

        #region 返回HttpResponestMessage类型
        /// <summary>
        /// 转为WebAPI用的HttpResponseMessage信息
        /// </summary>
        /// <param name="str">内容</param>
        /// <param name="formatter">默认格式是针对微信的转换</param>
        /// <returns></returns>
        public static HttpResponseMessage ToHttpResponseMsg(this String str, String formatter = "application/x-www-form-urlencoded")
        {
            var result = new HttpResponseMessage
            {
                Content = new StringContent(str, Encoding.GetEncoding("UTF-8"), formatter)
            };
            return result;
        }
        #endregion

        #region 返回单引号扩住的字符串
        /// <summary>
        /// 返回单引号扩住的字符串  
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <returns>单引号</returns>
        public static String ToSingleQuote(this String s)
        {
            return ("\'" + s + "\'");
        }
        #endregion

        #region 返回双引号扩住的字符串
        /// <summary>
        /// 返回双引号扩住的字符串  
        /// </summary>
        /// <param name="s">输入字符串</param>
        /// <returns>双引号</returns>
        public static String ToDoubleQuote(this String s)
        {
            return ("\"" + s + "\"");
        }
        #endregion

        #region 返回 数组
        /// <summary>
        /// 返回的 Int32[]
        /// <para>空字符串为0</para>
        /// </summary>
        /// <param name="s"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static Int32[] SplitToArray(this String s, params Char[] separator)
        {
            //try
            //{
            //    if (String.IsNullOrWhiteSpace(s))
            //        return new Int32[0];
            //    else
            //    {
            //        if (separator == null)
            //            separator = new[] { ',' };
            //        else if (separator.Length == 0)
            //            separator = new[] { ',' };

            //        return (Array.ConvertAll(s.Split(separator), Int32.Parse));
            //    }
            //}
            //catch (Exception ex)
            //{
            //    throw ex;
            //}

            return s.SplitToArray<Int32>(separator);
        }
        /// <summary>
        /// 返回的 T[]
        /// <para>空字符串为类型默认值</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="s"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static T[] SplitToArray<T>(this String s, params Char[] separator)
        {
            try
            {
                if (String.IsNullOrWhiteSpace(s))
                    return new T[0];
                else
                {
                    if (separator == null)
                        separator = new[] { ',' };
                    else if (separator.Length == 0)
                        separator = new[] { ',' };

                    Type tp = typeof(T);
                    var parse = tp.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder,
                                    new Type[] { typeof(String) },
                                    new ParameterModifier[] { new ParameterModifier(1) });

                    return (Array.ConvertAll(s.Split(separator), new Converter<String, T>(q =>
                    {
                        if (String.IsNullOrWhiteSpace(q))
                            return default(T);
                        else
                        {
                            if (tp.Name.ToUpper() == "STRING") // String没有parse方法，所以要自己判断
                            {
                                object obj = (object)q;
                                return (T)obj;
                            }
                            else
                            {
                                var parameters = new object[] { q };
                                dynamic v = parse.Invoke(null, parameters);
                                return v;
                            }

                        }
                    })));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 截取字符串
        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="s">被截取的字符串</param>
        /// <param name="startIndex">开始下标</param>
        /// <param name="length">截取长度，超过才截取</param>
        /// <param name="separator">截取后补上的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static String Interception(this String s, Int32 startIndex, Int32 length, String separator)
        {
            if (s.Length > length)
            {
                return (s.Substring(startIndex, length) + separator);
            }
            else
                return s;
        }
        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="s">被截取的字符串</param>
        /// <param name="startIndex">开始下标</param>
        /// <param name="length">截取长度，超过才截取</param>
        /// <param name="separator">截取后补上的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static String Interception(this String s, Int32 length)
        {
            return s.Interception(0, length, "......");
        }
        #endregion

        #region 判断字符串是否有值，就是不为 [null,"","   "]
        /// <summary>
        /// 判断字符串是否有值，就是不为 [null,"","   "]
        /// <para>有值为:true,否则为:false</para>
        /// </summary>
        /// <param name="s">输入字符串</param>
        public static Boolean HasValue(this String s)
        {
            return !String.IsNullOrWhiteSpace(s);
        }
        #endregion

        #region 判断字符串 [数组] 是否有值
        /// <summary>
        /// 判断字符串 [数组] 是否有值
        /// <para>有值为:true,否则为:false</para>
        /// </summary>
        /// <param name="s">字符串 [数组]</param>
        public static Boolean HasValue(this String[] s)
        {
            return (null != s && s.Length > 0);
        }
        #endregion

        #region 判断字符串 [集合] 是否有值
        /// <summary>
        /// 判断字符串 [集合] 是否有值
        /// <para>有值为:true,否则为:false</para>
        /// </summary>
        /// <param name="s">字符串 [集合]</param>
        public static Boolean HasValue(this IList<String> s)
        {
            return (null != s && s.Count > 0);
        }
        #endregion


    }
    #endregion

}
